home *** CD-ROM | disk | FTP | other *** search
/ Aminet 25 / Aminet 25 (1998)(GTI - Schatztruhe)[!][Jun 1998].iso / Aminet / game / shoot / ADoom_src_1_2.lha / ADoom_src / r_segs.c < prev    next >
C/C++ Source or Header  |  1998-03-01  |  19KB  |  814 lines

  1. // Emacs style mode select   -*- C++ -*- 
  2. //-----------------------------------------------------------------------------
  3. //
  4. // $Id:$
  5. //
  6. // Copyright (C) 1993-1996 by id Software, Inc.
  7. //
  8. // This source is available for distribution and/or modification
  9. // only under the terms of the DOOM Source Code License as
  10. // published by id Software. All rights reserved.
  11. //
  12. // The source is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
  15. // for more details.
  16. //
  17. // $Log:$
  18. //
  19. // DESCRIPTION:
  20. //    All the clipping: columns, horizontal spans, sky columns.
  21. //
  22. //-----------------------------------------------------------------------------
  23.  
  24.  
  25. static const char
  26. rcsid[] = "$Id: r_segs.c,v 1.3 1997/01/29 20:10:19 b1 Exp $";
  27.  
  28.  
  29.  
  30.  
  31.  
  32. #include <stdlib.h>
  33.  
  34. #include "i_system.h"
  35.  
  36. #include "doomdef.h"
  37. #include "doomstat.h"
  38.  
  39. #include "r_local.h"
  40. #include "r_sky.h"
  41.  
  42.  
  43. // OPTIMIZE: closed two sided lines as single sided
  44.  
  45. // True if any of the segs textures might be visible.
  46. boolean        segtextured;    
  47.  
  48. // False if the back side is the same plane.
  49. boolean        markfloor;    
  50. boolean        markceiling;
  51.  
  52. boolean        maskedtexture;
  53. int        toptexture;
  54. int        bottomtexture;
  55. int        midtexture;
  56.  
  57.  
  58. angle_t        rw_normalangle;
  59. // angle to line origin
  60. int        rw_angle1;    
  61.  
  62. //
  63. // regular wall
  64. //
  65. int        rw_x;
  66. int        rw_stopx;
  67. angle_t        rw_centerangle;
  68. fixed_t        rw_offset;
  69. fixed_t        rw_distance;
  70. fixed_t        rw_scale;
  71. fixed_t        rw_scalestep;
  72. fixed_t        rw_midtexturemid;
  73. fixed_t        rw_toptexturemid;
  74. fixed_t        rw_bottomtexturemid;
  75.  
  76. int        worldtop;
  77. int        worldbottom;
  78. int        worldhigh;
  79. int        worldlow;
  80.  
  81. fixed_t        pixhigh;
  82. fixed_t        pixlow;
  83. fixed_t        pixhighstep;
  84. fixed_t        pixlowstep;
  85.  
  86. fixed_t        topfrac;
  87. fixed_t        topstep;
  88.  
  89. fixed_t        bottomfrac;
  90. fixed_t        bottomstep;
  91.  
  92.  
  93. lighttable_t**    walllights;
  94.  
  95. short*        maskedtexturecol;
  96.  
  97.  
  98.  
  99. #ifndef AMIGA
  100. //
  101. // R_RenderMaskedSegRange
  102. //
  103. void
  104. R_RenderMaskedSegRange
  105. ( drawseg_t*    ds,
  106.   int        x1,
  107.   int        x2 )
  108. {
  109.     unsigned    index;
  110.     column_t*    col;
  111.     int        lightnum;
  112.     int        texnum;
  113.     
  114.     // Calculate light table.
  115.     // Use different light tables
  116.     //   for horizontal / vertical / diagonal. Diagonal?
  117.     // OPTIMIZE: get rid of LIGHTSEGSHIFT globally
  118.     curline = ds->curline;
  119.     frontsector = curline->frontsector;
  120.     backsector = curline->backsector;
  121.     texnum = texturetranslation[curline->sidedef->midtexture];
  122.     
  123.     lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT)+extralight;
  124.  
  125.     if (curline->v1->y == curline->v2->y)
  126.     lightnum--;
  127.     else if (curline->v1->x == curline->v2->x)
  128.     lightnum++;
  129.  
  130.     if (lightnum < 0)        
  131.     walllights = scalelight[0];
  132.     else if (lightnum >= LIGHTLEVELS)
  133.     walllights = scalelight[LIGHTLEVELS-1];
  134.     else
  135.     walllights = scalelight[lightnum];
  136.  
  137.     maskedtexturecol = ds->maskedtexturecol;
  138.  
  139.     rw_scalestep = ds->scalestep;        
  140.     spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep;
  141.     mfloorclip = ds->sprbottomclip;
  142.     mceilingclip = ds->sprtopclip;
  143.     
  144.     // find positioning
  145.     if (curline->linedef->flags & ML_DONTPEGBOTTOM)
  146.     {
  147.     dc_texturemid = frontsector->floorheight > backsector->floorheight
  148.         ? frontsector->floorheight : backsector->floorheight;
  149.     dc_texturemid = dc_texturemid + textureheight[texnum] - viewz;
  150.     }
  151.     else
  152.     {
  153.     dc_texturemid =frontsector->ceilingheight<backsector->ceilingheight
  154.         ? frontsector->ceilingheight : backsector->ceilingheight;
  155.     dc_texturemid = dc_texturemid - viewz;
  156.     }
  157.     dc_texturemid += curline->sidedef->rowoffset;
  158.             
  159.     if (fixedcolormap)
  160.     dc_colormap = fixedcolormap;
  161.     
  162.     // draw the columns
  163.     for (dc_x = x1 ; dc_x <= x2 ; dc_x++)
  164.     {
  165.     // calculate lighting
  166.     if (maskedtexturecol[dc_x] != MAXSHORT)
  167.     {
  168.         if (!fixedcolormap)
  169.         {
  170.         index = spryscale>>LIGHTSCALESHIFT;
  171.  
  172.         if (index >=  MAXLIGHTSCALE )
  173.             index = MAXLIGHTSCALE-1;
  174.  
  175.         dc_colormap = walllights[index];
  176.         }
  177.             
  178.         sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale);
  179.         dc_iscale = 0xffffffffu / (unsigned)spryscale;
  180.         
  181.         // draw the texture
  182.         col = (column_t *)( 
  183.         (byte *)R_GetColumn(texnum,maskedtexturecol[dc_x]) -3);
  184.             
  185. //#ifndef AMIGA
  186.         R_DrawMaskedColumn (col);
  187. //#else
  188. //        R_DrawMaskedColumnAmi (col, TYPE_NORMAL);
  189. //#endif
  190.         maskedtexturecol[dc_x] = MAXSHORT;
  191.     }
  192.     spryscale += rw_scalestep;
  193.     }
  194.     
  195. }
  196. #endif
  197.  
  198.  
  199.  
  200.  
  201. #ifdef AMIGA
  202.  
  203. extern void R_RenderSegLoop (void);
  204.  
  205. #else
  206.  
  207. //#define DO_STATS
  208.  
  209. #ifdef DO_STATS
  210. unsigned int stats[26] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  211. #define STATS(x) stats[x]++
  212. #else
  213. #define STATS(x)
  214. #endif
  215.  
  216.  
  217. //
  218. // R_RenderSegLoop
  219. // Draws zero, one, or two textures (and possibly a masked
  220. //  texture) for walls.
  221. // Can draw or mark the starting pixel of floor and ceiling
  222. //  textures.
  223. // CALLED: CORE LOOPING ROUTINE.
  224. //
  225. #define HEIGHTBITS        12
  226. #define HEIGHTUNIT        (1<<HEIGHTBITS)
  227.  
  228. void R_RenderSegLoop (void)
  229. {
  230.     angle_t        angle;
  231.     unsigned        index;
  232.     int            yl;
  233.     int            yh;
  234.     int            mid;
  235.     fixed_t        texturecolumn;
  236.     int            top;
  237.     int            bottom;
  238.  
  239.     //texturecolumn = 0;                // shut up compiler warning
  240.  
  241.     STATS(0);  /* 45443 */
  242.     for ( ; rw_x < rw_stopx ; rw_x++)
  243.     {
  244.         STATS(1);  /* 1603733 */
  245.     // mark floor / ceiling areas
  246.     yl = (topfrac+HEIGHTUNIT-1)>>HEIGHTBITS;
  247.  
  248.     // no space above wall?
  249.     if (yl < ceilingclip[rw_x]+1) {
  250.             STATS(2);  /* 1016131 */
  251.         yl = ceilingclip[rw_x]+1;
  252.     }
  253.  
  254.     if (markceiling)
  255.     {
  256.             STATS(3);  /* 1291140 */
  257.         top = ceilingclip[rw_x]+1;
  258.         bottom = yl-1;
  259.  
  260.         if (bottom >= floorclip[rw_x]) {
  261.                 STATS(4);  /* 50179 */
  262.         bottom = floorclip[rw_x]-1;
  263.             }
  264.         if (top <= bottom)
  265.         {
  266.                 STATS(5);  /* 439559 */
  267.         ceilingplane->top[rw_x] = top;
  268.         ceilingplane->bottom[rw_x] = bottom;
  269.         }
  270.     }
  271.         
  272.     yh = bottomfrac>>HEIGHTBITS;
  273.  
  274.     if (yh >= floorclip[rw_x]) {
  275.             STATS(6);  /* 670449 */
  276.         yh = floorclip[rw_x]-1;
  277.         }
  278.     if (markfloor)
  279.     {
  280.             STATS(7);  /* 1298743 */
  281.         top = yh+1;
  282.         bottom = floorclip[rw_x]-1;
  283.         if (top <= ceilingclip[rw_x]) {
  284.                 STATS(8);  /* 49048 */
  285.         top = ceilingclip[rw_x]+1;
  286.             }
  287.         if (top <= bottom)
  288.         {
  289.                 STATS(9);  /* 726501 */
  290.         floorplane->top[rw_x] = top;
  291.         floorplane->bottom[rw_x] = bottom;
  292.         }
  293.     }
  294.     
  295.     // texturecolumn and lighting are independent of wall tiers
  296.     if (segtextured)
  297.     {
  298.             STATS(10);  /* 1261482 */
  299.         // calculate texture offset
  300.         angle = (rw_centerangle + xtoviewangle[rw_x])>>ANGLETOFINESHIFT;
  301.         texturecolumn = rw_offset-FixedMul(finetangent[angle],rw_distance);
  302.         texturecolumn >>= FRACBITS;
  303.         // calculate lighting
  304.         index = rw_scale>>LIGHTSCALESHIFT;
  305.  
  306.         if (index >=  MAXLIGHTSCALE ) {
  307.                 STATS(11);  /* 169980 */
  308.         index = MAXLIGHTSCALE-1;
  309.             }
  310.         dc_colormap = walllights[index];
  311.         dc_x = rw_x;
  312.         dc_iscale = 0xffffffffu / (unsigned)rw_scale;
  313.     }
  314.     
  315.     // draw the wall tiers
  316.     if (midtexture)
  317.     {
  318.             STATS(12);  /* 560607 */
  319.         // single sided line
  320.         dc_yl = yl;
  321.         dc_yh = yh;
  322.         dc_texturemid = rw_midtexturemid;
  323.         dc_source = R_GetColumn(midtexture,texturecolumn);
  324.         colfunc ();
  325.         ceilingclip[rw_x] = viewheight;
  326.         floorclip[rw_x] = -1;
  327.     }
  328.     else
  329.     {
  330.             STATS(13);  /* 1043126 */
  331.         // two sided line
  332.         if (toptexture)
  333.         {
  334.                 STATS(14);  /* 314333 */
  335.         // top wall
  336.         mid = pixhigh>>HEIGHTBITS;
  337.         pixhigh += pixhighstep;
  338.  
  339.         if (mid >= floorclip[rw_x]) {
  340.                     STATS(15);  /* 45511 */
  341.             mid = floorclip[rw_x]-1;
  342.                 }
  343.         if (mid >= yl)
  344.         {
  345.                     STATS(16);  /* 139708 */
  346.             dc_yl = yl;
  347.             dc_yh = mid;
  348.             dc_texturemid = rw_toptexturemid;
  349.             dc_source = R_GetColumn(toptexture,texturecolumn);
  350.             colfunc ();
  351.             ceilingclip[rw_x] = mid;
  352.         }
  353.         else {
  354.                     STATS(17);  /* 174625 */
  355.             ceilingclip[rw_x] = yl-1;
  356.                 }
  357.         }
  358.         else
  359.         {
  360.                 STATS(18);  /* 728793 */
  361.         // no top wall
  362.         if (markceiling) {
  363.                     STATS(19);  /* 439926 */
  364.             ceilingclip[rw_x] = yl-1;
  365.                 }
  366.         }
  367.             
  368.         if (bottomtexture)
  369.         {
  370.                 STATS(20);  /* 446785 */
  371.         // bottom wall
  372.         mid = (pixlow+HEIGHTUNIT-1)>>HEIGHTBITS;
  373.         pixlow += pixlowstep;
  374.  
  375.         // no space above wall?
  376.         if (mid <= ceilingclip[rw_x]) {
  377.                     STATS(21);  /* 67461 */
  378.             mid = ceilingclip[rw_x]+1;
  379.         }
  380.         if (mid <= yh)
  381.         {
  382.                     STATS(22);  /* 366880 */
  383.             dc_yl = mid;
  384.             dc_yh = yh;
  385.             dc_texturemid = rw_bottomtexturemid;
  386.             dc_source = R_GetColumn(bottomtexture,
  387.                         texturecolumn);
  388.             colfunc ();
  389.             floorclip[rw_x] = mid;
  390.         }
  391.         else {
  392.                     STATS(23);  /* 79905 */
  393.             floorclip[rw_x] = yh+1;
  394.                 }
  395.         }
  396.         else
  397.         {
  398.                 STATS(24);  /* 596341 */
  399.         // no bottom wall
  400.         if (markfloor)
  401.             floorclip[rw_x] = yh+1;
  402.         }
  403.             
  404.         if (maskedtexture)
  405.         {
  406.                 STATS(25);  /* 0 */
  407.         // save texturecol
  408.         //  for backdrawing of masked mid texture
  409.         maskedtexturecol[rw_x] = texturecolumn;
  410.         }
  411.     }
  412.         
  413.     rw_scale += rw_scalestep;
  414.     topfrac += topstep;
  415.     bottomfrac += bottomstep;
  416.  
  417.     }
  418. }
  419.  
  420. #ifdef DO_STATS
  421. void _STDdo_stats (void)
  422. {
  423.   int i;
  424.  
  425.   for (i = 0; i < 26; i++)
  426.      printf ("stats[%2d] = %u\n", i, stats[i]);
  427. }
  428. #endif
  429.  
  430. #endif
  431.  
  432.  
  433.  
  434.  
  435. //
  436. // R_StoreWallRange
  437. // A wall segment will be drawn
  438. //  between start and stop pixels (inclusive).
  439. //
  440. void
  441. R_StoreWallRange
  442. ( int    start,
  443.   int    stop )
  444. {
  445.     fixed_t        hyp;
  446.     fixed_t        sineval;
  447.     angle_t        distangle, offsetangle;
  448.     fixed_t        vtop;
  449.     int            lightnum;
  450.  
  451.     // don't overflow and crash
  452.     if (ds_p == &drawsegs[MAXDRAWSEGS])
  453.     return;        
  454.         
  455. #ifdef RANGECHECK
  456.     if (start >=viewwidth || start > stop)
  457.     I_Error ("Bad R_RenderWallRange: %i to %i", start , stop);
  458. #endif
  459.     
  460.     sidedef = curline->sidedef;
  461.     linedef = curline->linedef;
  462.  
  463.     // mark the segment as visible for auto map
  464.     linedef->flags |= ML_MAPPED;
  465.     
  466.     // calculate rw_distance for scale calculation
  467.     rw_normalangle = curline->angle + ANG90;
  468.     offsetangle = iabs(rw_normalangle-rw_angle1);
  469.     
  470.     if (offsetangle > ANG90)
  471.     offsetangle = ANG90;
  472.  
  473.     distangle = ANG90 - offsetangle;
  474.     hyp = R_PointToDist (curline->v1->x, curline->v1->y);
  475.     sineval = finesine[distangle>>ANGLETOFINESHIFT];
  476.     rw_distance = FixedMul (hyp, sineval);
  477.         
  478.     
  479.     ds_p->x1 = rw_x = start;
  480.     ds_p->x2 = stop;
  481.     ds_p->curline = curline;
  482.     rw_stopx = stop+1;
  483.     
  484.     // calculate scale at both ends and step
  485.     ds_p->scale1 = rw_scale = 
  486.     R_ScaleFromGlobalAngle (viewangle + xtoviewangle[start]);
  487.     
  488.     if (stop > start )
  489.     {
  490.     ds_p->scale2 = R_ScaleFromGlobalAngle (viewangle + xtoviewangle[stop]);
  491.     ds_p->scalestep = rw_scalestep = 
  492.         (ds_p->scale2 - rw_scale) / (stop-start);
  493.     }
  494.     else
  495.     {
  496.     // UNUSED: try to fix the stretched line bug
  497. #if 0
  498.     if (rw_distance < FRACUNIT/2)
  499.     {
  500.         fixed_t        trx,try;
  501.         fixed_t        gxt,gyt;
  502.  
  503.         trx = curline->v1->x - viewx;
  504.         try = curline->v1->y - viewy;
  505.             
  506.         gxt = FixedMul(trx,viewcos); 
  507.         gyt = -FixedMul(try,viewsin); 
  508.         ds_p->scale1 = FixedDiv(projection, gxt-gyt)<<detailshift;
  509.     }
  510. #endif
  511.     ds_p->scale2 = ds_p->scale1;
  512.     }
  513.     
  514.     // calculate texture boundaries
  515.     //  and decide if floor / ceiling marks are needed
  516.     worldtop = frontsector->ceilingheight - viewz;
  517.     worldbottom = frontsector->floorheight - viewz;
  518.     
  519.     midtexture = toptexture = bottomtexture = maskedtexture = 0;
  520.     ds_p->maskedtexturecol = NULL;
  521.     
  522.     if (!backsector)
  523.     {
  524.     // single sided line
  525.     midtexture = texturetranslation[sidedef->midtexture];
  526.     // a single sided line is terminal, so it must mark ends
  527.     markfloor = markceiling = true;
  528.     if (linedef->flags & ML_DONTPEGBOTTOM)
  529.     {
  530.         vtop = frontsector->floorheight +
  531.         textureheight[sidedef->midtexture];
  532.         // bottom of texture at bottom
  533.         rw_midtexturemid = vtop - viewz;    
  534.     }
  535.     else
  536.     {
  537.         // top of texture at top
  538.         rw_midtexturemid = worldtop;
  539.     }
  540.     rw_midtexturemid += sidedef->rowoffset;
  541.  
  542.     ds_p->silhouette = SIL_BOTH;
  543.     ds_p->sprtopclip = screenheightarray;
  544.     ds_p->sprbottomclip = negonearray;
  545.     ds_p->bsilheight = MAXINT;
  546.     ds_p->tsilheight = MININT;
  547.     }
  548.     else
  549.     {
  550.     // two sided line
  551.     ds_p->sprtopclip = ds_p->sprbottomclip = NULL;
  552.     ds_p->silhouette = 0;
  553.     
  554.     if (frontsector->floorheight > backsector->floorheight)
  555.     {
  556.         ds_p->silhouette = SIL_BOTTOM;
  557.         ds_p->bsilheight = frontsector->floorheight;
  558.     }
  559.     else if (backsector->floorheight > viewz)
  560.     {
  561.         ds_p->silhouette = SIL_BOTTOM;
  562.         ds_p->bsilheight = MAXINT;
  563.         // ds_p->sprbottomclip = negonearray;
  564.     }
  565.     
  566.     if (frontsector->ceilingheight < backsector->ceilingheight)
  567.     {
  568.         ds_p->silhouette |= SIL_TOP;
  569.         ds_p->tsilheight = frontsector->ceilingheight;
  570.     }
  571.     else if (backsector->ceilingheight < viewz)
  572.     {
  573.         ds_p->silhouette |= SIL_TOP;
  574.         ds_p->tsilheight = MININT;
  575.         // ds_p->sprtopclip = screenheightarray;
  576.     }
  577.         
  578.     if (backsector->ceilingheight <= frontsector->floorheight)
  579.     {
  580.         ds_p->sprbottomclip = negonearray;
  581.         ds_p->bsilheight = MAXINT;
  582.         ds_p->silhouette |= SIL_BOTTOM;
  583.     }
  584.     
  585.     if (backsector->floorheight >= frontsector->ceilingheight)
  586.     {
  587.         ds_p->sprtopclip = screenheightarray;
  588.         ds_p->tsilheight = MININT;
  589.         ds_p->silhouette |= SIL_TOP;
  590.     }
  591.     
  592.     worldhigh = backsector->ceilingheight - viewz;
  593.     worldlow = backsector->floorheight - viewz;
  594.         
  595.     // hack to allow height changes in outdoor areas
  596.     if (frontsector->ceilingpic == skyflatnum 
  597.         && backsector->ceilingpic == skyflatnum)
  598.     {
  599.         worldtop = worldhigh;
  600.     }
  601.     
  602.             
  603.     if (worldlow != worldbottom 
  604.         || backsector->floorpic != frontsector->floorpic
  605.         || backsector->lightlevel != frontsector->lightlevel)
  606.     {
  607.         markfloor = true;
  608.     }
  609.     else
  610.     {
  611.         // same plane on both sides
  612.         markfloor = false;
  613.     }
  614.     
  615.             
  616.     if (worldhigh != worldtop 
  617.         || backsector->ceilingpic != frontsector->ceilingpic
  618.         || backsector->lightlevel != frontsector->lightlevel)
  619.     {
  620.         markceiling = true;
  621.     }
  622.     else
  623.     {
  624.         // same plane on both sides
  625.         markceiling = false;
  626.     }
  627.     
  628.     if (backsector->ceilingheight <= frontsector->floorheight
  629.         || backsector->floorheight >= frontsector->ceilingheight)
  630.     {
  631.         // closed door
  632.         markceiling = markfloor = true;
  633.     }
  634.     
  635.  
  636.     if (worldhigh < worldtop)
  637.     {
  638.         // top texture
  639.         toptexture = texturetranslation[sidedef->toptexture];
  640.         if (linedef->flags & ML_DONTPEGTOP)
  641.         {
  642.         // top of texture at top
  643.         rw_toptexturemid = worldtop;
  644.         }
  645.         else
  646.         {
  647.         vtop =
  648.             backsector->ceilingheight
  649.             + textureheight[sidedef->toptexture];
  650.         
  651.         // bottom of texture
  652.         rw_toptexturemid = vtop - viewz;    
  653.         }
  654.     }
  655.     if (worldlow > worldbottom)
  656.     {
  657.         // bottom texture
  658.         bottomtexture = texturetranslation[sidedef->bottomtexture];
  659.  
  660.         if (linedef->flags & ML_DONTPEGBOTTOM )
  661.         {
  662.         // bottom of texture at bottom
  663.         // top of texture at top
  664.         rw_bottomtexturemid = worldtop;
  665.         }
  666.         else    // top of texture at top
  667.         rw_bottomtexturemid = worldlow;
  668.     }
  669.     rw_toptexturemid += sidedef->rowoffset;
  670.     rw_bottomtexturemid += sidedef->rowoffset;
  671.     
  672.     // allocate space for masked texture tables
  673.     if (sidedef->midtexture)
  674.     {
  675.         // masked midtexture
  676.         maskedtexture = true;
  677.         ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw_x;
  678.         lastopening += rw_stopx - rw_x;
  679.     }
  680.     }
  681.     
  682.     // calculate rw_offset (only needed for textured lines)
  683.     segtextured = midtexture | toptexture | bottomtexture | maskedtexture;
  684.  
  685.     if (segtextured)
  686.     {
  687.     offsetangle = rw_normalangle-rw_angle1;
  688.     
  689.     if (offsetangle > ANG180)
  690.         offsetangle = -offsetangle;
  691.  
  692.     if (offsetangle > ANG90)
  693.         offsetangle = ANG90;
  694.  
  695.     sineval = finesine[offsetangle >>ANGLETOFINESHIFT];
  696.     rw_offset = FixedMul (hyp, sineval);
  697.  
  698.     if (rw_normalangle-rw_angle1 < ANG180)
  699.         rw_offset = -rw_offset;
  700.  
  701.     rw_offset += sidedef->textureoffset + curline->offset;
  702.     rw_centerangle = ANG90 + viewangle - rw_normalangle;
  703.     
  704.     // calculate light table
  705.     //  use different light tables
  706.     //  for horizontal / vertical / diagonal
  707.     // OPTIMIZE: get rid of LIGHTSEGSHIFT globally
  708.     if (!fixedcolormap)
  709.     {
  710.         lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT)+extralight;
  711.  
  712.         if (curline->v1->y == curline->v2->y)
  713.         lightnum--;
  714.         else if (curline->v1->x == curline->v2->x)
  715.         lightnum++;
  716.  
  717.         if (lightnum < 0)        
  718.         walllights = scalelight[0];
  719.         else if (lightnum >= LIGHTLEVELS)
  720.         walllights = scalelight[LIGHTLEVELS-1];
  721.         else
  722.         walllights = scalelight[lightnum];
  723.     }
  724.     }
  725.     
  726.     // if a floor / ceiling plane is on the wrong side
  727.     //  of the view plane, it is definitely invisible
  728.     //  and doesn't need to be marked.
  729.     
  730.   
  731.     if (frontsector->floorheight >= viewz)
  732.     {
  733.     // above view plane
  734.     markfloor = false;
  735.     }
  736.     
  737.     if (frontsector->ceilingheight <= viewz 
  738.     && frontsector->ceilingpic != skyflatnum)
  739.     {
  740.     // below view plane
  741.     markceiling = false;
  742.     }
  743.  
  744.     
  745.     // calculate incremental stepping values for texture edges
  746.     worldtop >>= 4;
  747.     worldbottom >>= 4;
  748.     
  749.     topstep = -FixedMul (rw_scalestep, worldtop);
  750.     topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw_scale);
  751.  
  752.     bottomstep = -FixedMul (rw_scalestep,worldbottom);
  753.     bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale);
  754.     
  755.  
  756.     if (backsector)
  757.     {    
  758.     worldhigh >>= 4;
  759.     worldlow >>= 4;
  760.  
  761.     if (worldhigh < worldtop)
  762.     {
  763.         pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale);
  764.         pixhighstep = -FixedMul (rw_scalestep,worldhigh);
  765.     }
  766.     
  767.     if (worldlow > worldbottom)
  768.     {
  769.         pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale);
  770.         pixlowstep = -FixedMul (rw_scalestep,worldlow);
  771.     }
  772.     }
  773.     
  774.     // render it
  775.     if (markceiling)
  776.     ceilingplane = R_CheckPlane (ceilingplane, rw_x, rw_stopx-1);
  777.     
  778.     if (markfloor)
  779.     floorplane = R_CheckPlane (floorplane, rw_x, rw_stopx-1);
  780.  
  781.     R_RenderSegLoop ();
  782.  
  783.     
  784.     // save sprite clipping info
  785.     if ( ((ds_p->silhouette & SIL_TOP) || maskedtexture)
  786.      && !ds_p->sprtopclip)
  787.     {
  788.     memcpy (lastopening, ceilingclip+start, 2*(rw_stopx-start));
  789.     ds_p->sprtopclip = lastopening - start;
  790.     lastopening += rw_stopx - start;
  791.     }
  792.     
  793.     if ( ((ds_p->silhouette & SIL_BOTTOM) || maskedtexture)
  794.      && !ds_p->sprbottomclip)
  795.     {
  796.     memcpy (lastopening, floorclip+start, 2*(rw_stopx-start));
  797.     ds_p->sprbottomclip = lastopening - start;
  798.     lastopening += rw_stopx - start;    
  799.     }
  800.  
  801.     if (maskedtexture && !(ds_p->silhouette&SIL_TOP))
  802.     {
  803.     ds_p->silhouette |= SIL_TOP;
  804.     ds_p->tsilheight = MININT;
  805.     }
  806.     if (maskedtexture && !(ds_p->silhouette&SIL_BOTTOM))
  807.     {
  808.     ds_p->silhouette |= SIL_BOTTOM;
  809.     ds_p->bsilheight = MAXINT;
  810.     }
  811.     ds_p++;
  812. }
  813.  
  814.